<template>
  <Dialog
    :visible="visible"
    modal
    :style="{ width: isFullscreen ? '100vw' : '95vw', height: isFullscreen ? '100vh' : '90vh' }"
    :closable="false"
    :draggable="false"
    :maximizable="false"
    @update:visible="$emit('update:visible', $event)"
    @hide="handleClose"
    class="bpmn-designer-dialog"
    :class="{ 'fullscreen': isFullscreen }"
  >
    <!-- 自定义头部 -->
    <template #header>
      <div class="dialog-header">
        <h3>BPMN流程设计器</h3>
        <div class="header-actions">
          <Button
            icon="pi pi-undo"
            icon-only
            size="small"
            text
            @click="handleUndo"
            :disabled="!canUndo"
            title="撤销"
          />
          <Button
            icon="pi pi-redo"
            icon-only
            size="small"
            text
            @click="handleRedo"
            :disabled="!canRedo"
            title="重做"
          />
          <Button
            :icon="isFullscreen ? 'pi pi-window-minimize' : 'pi pi-window-maximize'"
            icon-only
            size="small"
            text
            @click="toggleFullscreen"
            :title="isFullscreen ? '退出全屏' : '全屏'"
          />
          <Button
            icon="pi pi-upload"
            icon-only
            size="small"
            text
            @click="triggerFileInput"
            title="上传XML文件"
          />
          <Button
            icon="pi pi-image"
            icon-only
            size="small"
            text
            @click="exportSvg"
            title="导出SVG"
          />
          <Button
            icon="pi pi-times"
            icon-only
            size="small"
            text
            @click="handleClose"
            title="关闭"
          />
        </div>
      </div>
    </template>

    <div class="bpmn-designer">
      <!-- 工具栏 -->
      <div class="designer-toolbar">
        <div class="toolbar-left">
          <Button
            icon="pi pi-file"
            label="新建"
            size="small"
            @click="createNewDiagram"
          />
          <Button
            icon="pi pi-save"
            label="保存"
            size="small"
            severity="success"
            @click="saveDiagram"
          />
          <Button
            icon="pi pi-code"
            label="查看XML"
            size="small"
            severity="info"
            @click="openXmlDialog"
          />
          <Button
            icon="pi pi-upload"
            label="上传XML"
            size="small"
            severity="secondary"
            @click="triggerFileUpload"
          />
          <input
            ref="fileInput"
            type="file"
            accept=".xml,.bpmn"
            style="display: none"
            @change="handleFileUpload"
          />
        </div>
        
        <div class="toolbar-right">
          <Button
            icon="pi pi-download"
            label="下载XML"
            size="small"
            severity="secondary"
            @click="exportXml"
          />
          <div class="zoom-controls">
            <Button
              icon="pi pi-search-minus"
              icon-only
              size="small"
              text
              @click="zoomOut"
              title="缩小"
            />
            <span class="zoom-level">{{ Math.round(currentZoom * 100) }}%</span>
            <Button
              icon="pi pi-search-plus"
              icon-only
              size="small"
              text
              @click="zoomIn"
              title="放大"
            />
            <Button
              icon="pi pi-refresh"
              icon-only
              size="small"
              text
              @click="resetZoom"
              title="重置缩放"
            />
          </div>
        </div>
      </div>
      
      <!-- 主设计区域 -->
      <div class="designer-main">

        
        <!-- BPMN画布 -->
        <div class="designer-container">
          <div ref="bpmnContainer" class="bpmn-canvas"></div>
          <div v-if="!isModelerReady" class="loading-overlay">
            <i class="pi pi-spin pi-spinner" style="font-size: 2rem;"></i>
            <Button
              label="重新初始化"
              size="small"
              severity="secondary"
              @click="retryInit"
              style="margin-top: 16px;"
            />
          </div>
        </div>
        
          <!-- 右侧属性面板 -->
          <div class="properties-panel" :class="{ 'panel-collapsed': !showProperties }">
            <!-- 左边缘折叠按钮 -->
            <div class="panel-toggle-button" @click="toggleProperties">
              <i :class="showProperties ? 'pi pi-chevron-right' : 'pi pi-chevron-left'"></i>
            </div>
            
            <div v-if="showProperties" class="panel-content">
            <div ref="propertiesContainer">
              <div v-if="!selectedElement" class="no-selection">
                <i class="pi pi-info-circle"></i>
              </div>
              <div v-else class="properties-tabs">
                <TabView v-model:activeIndex="activeTabIndex" class="custom-tabs">
                  <TabPanel header="常规配置" value="general">
                    <div class="tab-content">
                      <div class="form-group">
                        <label>节点ID</label>
                        <InputText 
                          v-model="elementProperties.id" 
                          placeholder="请输入节点ID"
                          readonly
                          class="w-full"
                        />
                      </div>
                      <div class="form-group">
                        <label>名称</label>
                        <InputText 
                          v-model="elementProperties.name" 
                          placeholder="请输入节点名称"
                          class="w-full"
                        />
                      </div>
                      <div class="form-group">
                        <label>描述</label>
                        <Textarea 
                          v-model="elementProperties.documentation" 
                          placeholder="请输入节点描述"
                          rows="3"
                          class="w-full"
                        />
                      </div>
                    </div>
                  </TabPanel>
                  
                  <TabPanel header="任务配置" value="task">
                    <div class="tab-content">
                      <div class="form-group">
                        <label>审批人</label>
                        <InputText 
                          v-model="elementProperties.assignee" 
                          placeholder="请输入审批人"
                          class="w-full"
                        />
                      </div>
                      <div class="form-group">
                        <label>候选审批人</label>
                        <InputText 
                          v-model="elementProperties.candidateUsers" 
                          placeholder="请输入候选审批人，多个用逗号分隔"
                          class="w-full"
                        />
                      </div>
                      <div class="form-group">
                        <label>候选审批组</label>
                        <InputText 
                          v-model="elementProperties.candidateGroups" 
                          placeholder="请输入候选审批组，多个用逗号分隔"
                          class="w-full"
                        />
                      </div>
                      <div class="form-group">
                        <label>抄送人</label>
                        <InputText 
                          v-model="elementProperties.ccUsers" 
                          placeholder="请输入抄送人，多个用逗号分隔"
                          class="w-full"
                        />
                      </div>
                    </div>
                  </TabPanel>
                  
                  <TabPanel header="监听配置" value="listener">
                    <div class="tab-content">
                      <div class="form-group">
                        <label>任务监听器</label>
                        <Textarea 
                          v-model="elementProperties.taskListeners" 
                          placeholder="请输入任务监听器配置"
                          rows="4"
                          class="w-full"
                        />
                      </div>
                      <div class="form-group">
                        <label>执行监听器</label>
                        <Textarea 
                          v-model="elementProperties.executionListeners" 
                          placeholder="请输入执行监听器配置"
                          rows="4"
                          class="w-full"
                        />
                      </div>
                    </div>
                  </TabPanel>
                  
                  <TabPanel header="其他配置" value="other">
                    <div class="tab-content">
                      <div class="form-group">
                        <label>扩展属性</label>
                        <Textarea 
                          v-model="elementProperties.extensionProperties" 
                          placeholder="请输入扩展属性配置"
                          rows="3"
                          class="w-full"
                        />
                      </div>
                      <div class="form-group">
                        <label>优先级</label>
                        <InputNumber 
                          v-model="elementProperties.priority" 
                          placeholder="请输入优先级"
                          class="w-full"
                          :min="0"
                          :max="100"
                        />
                      </div>
                      <div class="form-group">
                        <label>到期日表达式</label>
                        <InputText 
                          v-model="elementProperties.dueDate" 
                          placeholder="请输入到期日表达式，如：PT1H"
                          class="w-full"
                        />
                      </div>
                    </div>
                  </TabPanel>
                </TabView>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <Button
          label="取消"
          severity="secondary"
          @click="handleClose"
        />
        <Button
          label="确定使用"
          severity="primary"
          icon="pi pi-check"
          @click="handleConfirm"
        />
      </div>
    </template>
  </Dialog>

  <!-- XML查看对话框 -->
  <Dialog
    v-model:visible="showXmlDialog"
    modal
    :style="{ width: '80vw', height: '80vh' }"
    :closable="true"
    :draggable="false"
    :maximizable="true"
    header="流程图XML"
    class="xml-dialog"
  >
    <div class="xml-content">
      <div class="xml-toolbar">
        <Button
          icon="pi pi-copy"
          label="复制XML"
          size="small"
          severity="secondary"
          @click="copyXml"
        />
        <Button
          icon="pi pi-download"
          label="下载XML"
          size="small"
          severity="success"
          @click="downloadXml"
        />
        <Button
          icon="pi pi-refresh"
          label="刷新"
          size="small"
          severity="info"
          @click="refreshXml"
        />
      </div>
      <div class="xml-editor">
        <pre><code>{{ currentXml }}</code></pre>
      </div>
    </div>
  </Dialog>
</template>

<script setup lang="ts">
import { ref, watch, onUnmounted, nextTick } from 'vue'
import Dialog from 'primevue/dialog'
import Button from 'primevue/button'
import TabView from 'primevue/tabview'
import TabPanel from 'primevue/tabpanel'
import InputText from 'primevue/inputtext'
import Textarea from 'primevue/textarea'
import InputNumber from 'primevue/inputnumber'
import BpmnModeler from 'bpmn-js/lib/Modeler'
// @ts-ignore
import { BpmnPropertiesPanelModule } from 'bpmn-js-properties-panel'
// @ts-ignore
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'

interface Props {
  visible: boolean
  initialXml?: string
}

interface Emits {
  (e: 'update:visible', value: boolean): void
  (e: 'save', xml: string): void
  (e: 'close'): void
}

const props = withDefaults(defineProps<Props>(), {
  initialXml: ''
})

const emit = defineEmits<Emits>()

// 引用
const bpmnContainer = ref<HTMLElement | null>(null)
const propertiesContainer = ref<HTMLElement | null>(null)
const fileInput = ref<HTMLInputElement | null>(null)

// 状态
const isModelerReady = ref(false)
const showProperties = ref(true)
const selectedElement = ref<any>(null)
const isFullscreen = ref(false)
const activeTabIndex = ref(0)
const showXmlDialog = ref(false)
const currentXml = ref('')

// 节点属性
const elementProperties = ref({
  id: '',
  name: '',
  documentation: '',
  assignee: '',
  candidateUsers: '',
  candidateGroups: '',
  ccUsers: '',
  taskListeners: '',
  executionListeners: '',
  extensionProperties: '',
  priority: 0,
  dueDate: ''
})
const currentZoom = ref(1)
const canUndo = ref(false)
const canRedo = ref(false)
// showCanvasTips 已删除

// 标签页相关状态已在上方声明

// 节点属性数据已使用elementProperties替代

// BPMN Modeler实例
let modeler: any = null
let propertiesPanel: any = null

// 完全空白的BPMN XML - 只包含基本的定义结构
const emptyBpmnXml = `<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
  <bpmn:process id="Process_1" isExecutable="true">
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>`

// XML验证和清理函数
const validateAndCleanXml = (xml: string): string => {
  if (!xml || xml.trim() === '') {
    return emptyBpmnXml
  }
  
  // 检查是否是有效的BPMN XML
  if (!xml.includes('<bpmn:definitions') && !xml.includes('<definitions')) {
    console.warn('XML不是有效的BPMN格式，使用默认XML')
    return emptyBpmnXml
  }
  
  // 清理XML中的换行和多余空格
  let cleanedXml = xml.trim()
  
  // 确保XML声明存在
  if (!cleanedXml.startsWith('<?xml')) {
    cleanedXml = '<?xml version="1.0" encoding="UTF-8"?>\n' + cleanedXml
  }
  
  // 确保有正确的命名空间
  if (!cleanedXml.includes('xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"')) {
    console.warn('XML缺少必要的BPMN命名空间，使用默认XML')
    return emptyBpmnXml
  }
  
  return cleanedXml
}






// 监听visible变化
watch(() => props.visible, async (newVal) => {
  if (newVal) {
    await nextTick()
    setTimeout(async () => {
      if (bpmnContainer.value) {
        await initModeler()
      }
    }, 100)
  }
})

// 初始化BPMN Modeler
const initModeler = async () => {
  if (!bpmnContainer.value || !propertiesContainer.value) {
    console.error('BPMN容器或属性面板容器未找到')
    return
  }
  
  console.log('开始初始化增强版BPMN Modeler...')
  isModelerReady.value = false
  
  try {
    // 清理之前的实例
    if (modeler) {
      modeler.destroy()
      modeler = null
    }
    
    if (propertiesPanel) {
      try {
        propertiesPanel.destroy()
      } catch (error) {
        console.warn('属性面板销毁失败:', error)
      }
      propertiesPanel = null
    }
    
    // 确保容器有尺寸
    const container = bpmnContainer.value
    if (container.offsetWidth === 0 || container.offsetHeight === 0) {
      console.warn('容器尺寸为0，等待容器渲染...')
      setTimeout(() => initModeler(), 200)
      return
    }
    
    console.log('容器尺寸:', container.offsetWidth, 'x', container.offsetHeight)
    
    // 临时抑制已弃用API的警告
    const originalWarn = console.warn
    console.warn = function(...args) {
      const message = args.join(' ')
      if (message.includes('ContextPad#getPad is deprecated')) {
        return // 忽略这个特定的警告
      }
      originalWarn.apply(console, args)
    }
    
    // 创建BPMN Modeler实例
    modeler = new BpmnModeler({
      container: container,
      propertiesPanel: {
        parent: propertiesContainer.value
      },
      additionalModules: [
        BpmnPropertiesPanelModule
      ],
      moddleExtensions: {
        camunda: camundaModdleDescriptor
      }
      // 注意：根据bpmn-js最新版本，keyboard.bindTo配置已被移除，键盘绑定现在是隐式的
    })
    
    // 尝试初始化属性面板
    try {
      const propertiesPanel = modeler.get('propertiesPanel')
      if (propertiesPanel && propertiesContainer.value) {
        // 显式附加属性面板到容器
        propertiesPanel.attachTo(propertiesContainer.value)
        console.log('属性面板已成功附加到容器')
      }
    } catch (e) {
      console.warn('初始化属性面板失败:', e)
    }
    
    console.log('增强版BPMN Modeler实例创建成功')
    
    // 恢复原始的console.warn
    console.warn = originalWarn
    
    // 获取属性面板实例
    try {
      propertiesPanel = modeler.get('propertiesPanel')
      if (propertiesPanel) {
        console.log('属性面板实例获取成功')
      } else {
        console.warn('属性面板实例获取失败')
      }
    } catch (error) {
      console.warn('获取属性面板实例时出错:', error)
      propertiesPanel = null
    }
    
    // 监听元素选择事件
    modeler.on('selection.changed', (event: any) => {
      const element = event.newSelection[0]
      selectedElement.value = element
      console.log('选中元素:', element?.id, element?.type)
      
      // 选中元素时更新属性面板数据并自动展开
      if (element) {
        updateNodeProperties(element)
        // 自动展开属性面板
        if (!showProperties.value) {
          showProperties.value = true
          console.log('自动展开属性面板')
        }
      }
    })
    
    // 监听命令栈变化，用于撤销/重做功能
    try {
      const eventBus = modeler.get('eventBus')
      if (eventBus && typeof eventBus.on === 'function') {
        eventBus.on('commandStack.changed', () => {
          updateUndoRedoState()
        })
        console.log('命令栈变化事件监听已设置')
        
        // 监听元素创建事件
        eventBus.on('create.end', (event: any) => {
          console.log('元素创建完成:', event.element)
          if (event.element && !showProperties.value) {
            showProperties.value = true
            console.log('创建元素后自动展开属性面板')
          }
        })
        
        // 监听元素编辑事件
        eventBus.on('element.changed', (event: any) => {
          console.log('元素编辑完成:', event.element)
          if (event.element && !showProperties.value) {
            showProperties.value = true
            console.log('编辑元素后自动展开属性面板')
          }
        })
        
        // 监听元素移动事件
        eventBus.on('shape.move.end', (event: any) => {
          console.log('元素移动完成:', event.shape)
          if (event.shape && !showProperties.value) {
            showProperties.value = true
            console.log('移动元素后自动展开属性面板')
          }
        })
        
        // 监听连接线创建事件
        eventBus.on('connect.end', (event: any) => {
          console.log('连接线创建完成:', event.connection)
          if (event.connection && !showProperties.value) {
            showProperties.value = true
            console.log('创建连接线后自动展开属性面板')
          }
        })
        
        console.log('元素操作事件监听已设置')
      } else {
        console.warn('无法获取有效的eventBus实例')
      }
    } catch (error) {
      console.warn('设置命令栈监听失败:', error)
    }
    
    // 定义canvas变量
    let canvas: any = null
    
    // 监听缩放变化
    try {
      canvas = modeler.get('canvas')
      const eventBus = modeler.get('eventBus')
      
      if (canvas && eventBus && typeof eventBus.on === 'function') {
        eventBus.on('canvas.zoom', () => {
          try {
            if (canvas && typeof canvas.zoom === 'function') {
              currentZoom.value = canvas.zoom()
            }
          } catch (zoomError) {
            console.warn('获取缩放值失败:', zoomError)
          }
        })
        console.log('缩放变化事件监听已设置')
      } else {
        console.warn('无法获取有效的canvas或eventBus实例')
      }
    } catch (error) {
      console.warn('设置缩放监听失败:', error)
    }
    
    // 导入BPMN XML
    const xmlToImport = props.initialXml || emptyBpmnXml
    console.log('开始导入XML...')
    
    // 验证和清理XML
    const cleanedXml = validateAndCleanXml(xmlToImport)
    await modeler.importXML(cleanedXml)
    console.log('XML导入成功')
    
    // 默认选择第一个节点并显示其属性
    setTimeout(() => {
      try {
        const elementRegistry = modeler.get('elementRegistry')
        const selection = modeler.get('selection')
        
        // 获取所有元素
        const elements = elementRegistry.getAll()
        console.log('所有元素:', elements)
        
        // 查找第一个可选择的元素（排除根元素和连接线）
        const selectableElement = elements.find((element: any) => {
          return element.type !== 'bpmn:Process' && 
                 element.type !== 'bpmn:Definitions' &&
                 element.type !== 'bpmn:BPMNDiagram' &&
                 element.type !== 'bpmn:BPMNPlane' &&
                 !element.type.includes('bpmndi:') &&
                 element.id !== 'Process_1' &&
                 element.id !== 'Definitions_1' &&
                 element.id !== 'BPMNDiagram_1' &&
                 element.id !== 'BPMNPlane_1'
        })
        
        if (selectableElement) {
          console.log('默认选择元素:', selectableElement)
          selection.select(selectableElement)
          selectedElement.value = selectableElement
          updateNodeProperties(selectableElement)
        } else {
          console.log('没有找到可选择的元素，显示默认提示')
        }
      } catch (error) {
        console.warn('默认选择元素失败:', error)
      }
    }, 500)
    
    console.log('BPMN设计器中文汉化配置完成')
    
    // 获取画布并居中显示
    try {
      if (!canvas) {
        canvas = modeler.get('canvas')
      }
      if (canvas && typeof (canvas as any).zoom === 'function') {
        (canvas as any).zoom('fit-viewport')
        currentZoom.value = (canvas as any).zoom()
        console.log('画布缩放设置完成')
      } else {
        console.warn('无法获取有效的canvas实例或zoom方法不可用')
      }
    } catch (zoomError) {
      console.warn('设置画布缩放失败:', zoomError)
    }
    
    // 更新撤销/重做状态
    updateUndoRedoState()
    
    isModelerReady.value = true
    console.log('增强版BPMN Modeler 初始化完成')
  } catch (error: any) {
    console.error('增强版BPMN Modeler 初始化失败:', error)
    console.error('错误详情:', error.message)
    console.error('错误堆栈:', error.stack)
    isModelerReady.value = true
    alert(`BPMN设计器初始化失败: ${error.message}`)
  }
}

// 这个函数已被下面的updateNodeProperties函数替代

// 这些函数已被新的属性面板结构替代

// 更新撤销/重做状态
const updateUndoRedoState = () => {
  if (!modeler) return
  
  try {
    const commandStack = modeler.get('commandStack')
    // 检查commandStack是否存在以及方法是否可用
    if (commandStack && typeof commandStack.canUndo === 'function' && typeof commandStack.canRedo === 'function') {
      canUndo.value = commandStack.canUndo()
      canRedo.value = commandStack.canRedo()
    } else {
      console.warn('commandStack方法不可用')
      canUndo.value = false
      canRedo.value = false
    }
  } catch (error) {
    console.warn('更新撤销/重做状态失败:', error)
    canUndo.value = false
    canRedo.value = false
  }
}

// 处理撤销
const handleUndo = () => {
  if (!modeler || !canUndo.value) return
  
  try {
    const commandStack = modeler.get('commandStack')
    if (commandStack && typeof commandStack.undo === 'function') {
      commandStack.undo()
      updateUndoRedoState()
    } else {
      console.warn('撤销方法不可用')
    }
  } catch (error) {
    console.error('撤销操作失败:', error)
  }
}

// 处理重做
const handleRedo = () => {
  if (!modeler || !canRedo.value) return
  
  try {
    const commandStack = modeler.get('commandStack')
    if (commandStack && typeof commandStack.redo === 'function') {
      commandStack.redo()
      updateUndoRedoState()
    } else {
      console.warn('重做方法不可用')
    }
  } catch (error) {
    console.error('重做操作失败:', error)
  }
}

// 显示XML对话框
const openXmlDialog = async () => {
  if (!modeler) return
  
  try {
    const { xml } = await modeler.saveXML({ format: true })
    currentXml.value = xml || ''
    showXmlDialog.value = true
    console.log('XML获取成功')
  } catch (error) {
    console.error('获取XML失败:', error)
    alert('获取XML失败')
  }
}

// 刷新XML内容
const refreshXml = async () => {
  if (!modeler) return
  
  try {
    const { xml } = await modeler.saveXML({ format: true })
    currentXml.value = xml || ''
    console.log('XML刷新成功')
  } catch (error) {
    console.error('刷新XML失败:', error)
  }
}

// 复制XML到剪贴板
const copyXml = async () => {
  try {
    await navigator.clipboard.writeText(currentXml.value)
    alert('XML已复制到剪贴板')
  } catch (error) {
    console.error('复制失败:', error)
    // 降级方案
    const textArea = document.createElement('textarea')
    textArea.value = currentXml.value
    document.body.appendChild(textArea)
    textArea.select()
    document.execCommand('copy')
    document.body.removeChild(textArea)
    alert('XML已复制到剪贴板')
  }
}

// 下载XML文件
const downloadXml = () => {
  try {
    const blob = new Blob([currentXml.value], { type: 'application/xml' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `bpmn_diagram_${Date.now()}.xml`
    a.click()
    URL.revokeObjectURL(url)
    console.log('XML下载成功')
  } catch (error) {
    console.error('下载XML失败:', error)
  }
}

// 元素面板始终显示 - 已移除折叠功能

// hideCanvasTips 函数已删除

// 切换属性面板显示
const toggleProperties = () => {
  showProperties.value = !showProperties.value
}

// 切换全屏
const toggleFullscreen = async () => {
  try {
    const dialogElement = document.querySelector('.bpmn-designer-dialog')
    
    if (!dialogElement) {
      console.warn('找不到设计器对话框元素')
      return
    }
    
    // 如果当前不是全屏状态，进入全屏
    if (!document.fullscreenElement) {
      if (dialogElement.requestFullscreen) {
        await dialogElement.requestFullscreen()
      } else if ((dialogElement as any).webkitRequestFullscreen) {
        await (dialogElement as any).webkitRequestFullscreen()
      } else if ((dialogElement as any).msRequestFullscreen) {
        await (dialogElement as any).msRequestFullscreen()
      }
      isFullscreen.value = true
      console.log('进入全屏模式')
    } else {
      // 如果当前是全屏状态，退出全屏
      if (document.exitFullscreen) {
        await document.exitFullscreen()
      } else if ((document as any).webkitExitFullscreen) {
        await (document as any).webkitExitFullscreen()
      } else if ((document as any).msExitFullscreen) {
        await (document as any).msExitFullscreen()
      }
      isFullscreen.value = false
      console.log('退出全屏模式')
    }
  } catch (error) {
    console.error('切换全屏模式失败:', error)
  }
}

// 更新节点属性
const updateNodeProperties = (element: any) => {
  if (!element) return
  
  // 更新基本属性
  elementProperties.value.id = element.id || ''
  elementProperties.value.name = element.businessObject?.name || ''
  elementProperties.value.documentation = element.businessObject?.documentation?.[0]?.text || ''
  
  // 更新任务相关属性
  const bo = element.businessObject
  if (bo) {
    elementProperties.value.assignee = bo.assignee || ''
    elementProperties.value.candidateUsers = bo.candidateUsers || ''
    elementProperties.value.candidateGroups = bo.candidateGroups || ''
    elementProperties.value.priority = bo.priority || 0
    elementProperties.value.dueDate = bo.dueDate || ''
  }
  
  console.log('更新节点属性:', elementProperties.value)
}

// 创建新流程图
const createNewDiagram = async () => {
  if (!modeler) return
  
  try {
    await modeler.importXML(emptyBpmnXml)
    const canvas = modeler.get('canvas')
    if (canvas && typeof canvas.zoom === 'function') {
      canvas.zoom('fit-viewport')
      console.log('创建新流程图成功')
    } else {
      console.warn('无法获取有效的canvas实例或zoom方法不可用')
    }
  } catch (error) {
    console.error('创建新流程图失败:', error)
  }
}

// 触发文件选择
const triggerFileInput = () => {
  fileInput.value?.click()
}

// 处理文件上传
const triggerFileUpload = () => {
  fileInput.value?.click()
}

const handleFileUpload = async (event: Event) => {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0]
  
  if (!file || !modeler) return
  
  try {
    const text = await file.text()
    await modeler.importXML(text)
    const canvas = modeler.get('canvas')
    if (canvas && typeof canvas.zoom === 'function') {
      canvas.zoom('fit-viewport')
      console.log('导入XML成功')
    } else {
      console.warn('无法获取有效的canvas实例或zoom方法不可用')
    }
  } catch (error) {
    console.error('导入XML失败:', error)
    alert('导入XML失败，请检查文件格式')
  }
  
  // 重置文件输入
  target.value = ''
}

// 保存流程图
const saveDiagram = async () => {
  if (!modeler) return
  
  try {
    const { xml } = await modeler.saveXML({ format: true })
    console.log('流程图已保存:', xml)
    alert('流程图已保存到内存')
  } catch (error) {
    console.error('保存流程图失败:', error)
  }
}

// 导出XML
const exportXml = async () => {
  if (!modeler) return
  
  try {
    const { xml } = await modeler.saveXML({ format: true })
    
    // 创建下载链接
    const blob = new Blob([xml || ''], { type: 'application/xml' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `bpmn_diagram_${Date.now()}.xml`
    a.click()
    URL.revokeObjectURL(url)
    
    console.log('导出XML成功')
  } catch (error) {
    console.error('导出XML失败:', error)
  }
}

// 导出SVG
const exportSvg = async () => {
  if (!modeler) return
  
  try {
    const { svg } = await modeler.saveSVG()
    
    // 创建下载链接
    const blob = new Blob([svg || ''], { type: 'image/svg+xml' })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `bpmn_diagram_${Date.now()}.svg`
    a.click()
    URL.revokeObjectURL(url)
    
    console.log('导出SVG成功')
  } catch (error) {
    console.error('导出SVG失败:', error)
  }
}

// 缩放控制
const zoomIn = () => {
  if (!modeler) return
  try {
    const canvas = modeler.get('canvas')
    if (canvas && typeof canvas.zoom === 'function') {
      const currentZoom = canvas.zoom()
      canvas.zoom(currentZoom + 0.1)
    } else {
      console.warn('无法获取有效的canvas实例或zoom方法不可用')
    }
  } catch (error) {
    console.warn('放大操作失败:', error)
  }
}

const zoomOut = () => {
  if (!modeler) return
  try {
    const canvas = modeler.get('canvas')
    if (canvas && typeof canvas.zoom === 'function') {
      const currentZoom = canvas.zoom()
      canvas.zoom(currentZoom - 0.1)
    } else {
      console.warn('无法获取有效的canvas实例或zoom方法不可用')
    }
  } catch (error) {
    console.warn('缩小操作失败:', error)
  }
}

const resetZoom = () => {
  if (!modeler) return
  try {
    const canvas = modeler.get('canvas')
    if (canvas && typeof canvas.zoom === 'function') {
      canvas.zoom('fit-viewport')
    } else {
      console.warn('无法获取有效的canvas实例或zoom方法不可用')
    }
  } catch (error) {
    console.warn('重置缩放失败:', error)
  }
}

// 重试初始化
const retryInit = async () => {
  console.log('用户手动重试初始化BPMN设计器')
  await initModeler()
}

// 处理确认
const handleConfirm = async () => {
  if (!modeler) {
    emit('update:visible', false)
    return
  }
  
  try {
    const { xml } = await modeler.saveXML({ format: true })
    emit('save', xml || '')
    emit('update:visible', false)
  } catch (error) {
    console.error('获取XML失败:', error)
    alert('获取流程XML失败')
  }
}

// 处理关闭
const handleClose = () => {
  emit('update:visible', false)
  emit('close')
}

// 组件卸载时清理
onUnmounted(() => {
  if (propertiesPanel) {
    try {
      propertiesPanel.destroy()
    } catch (error) {
      console.warn('属性面板销毁失败:', error)
    }
    propertiesPanel = null
  }
  if (modeler) {
    try {
      modeler.destroy()
    } catch (error) {
      console.warn('BPMN Modeler销毁失败:', error)
    }
    modeler = null
  }
})
</script>

<style>
/* BPMN.js 必需的全局样式 */
@import 'bpmn-js/dist/assets/diagram-js.css';
@import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
@import 'bpmn-js/dist/assets/bpmn-js.css';
@import '@bpmn-io/properties-panel/dist/assets/properties-panel.css';
</style>

<style scoped>

.bpmn-designer {
  display: flex;
  flex-direction: column;
  height: calc(90vh - 120px);
}

.designer-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: #fafafa;
  border-bottom: 1px solid #e8e8e8;
  flex-shrink: 0;
}

.toolbar-left,
.toolbar-right {
  display: flex;
  gap: 8px;
  align-items: center;
}

.designer-main {
  display: flex;
  flex: 1;
  overflow: hidden;
}

.designer-container {
  flex: 1;
  position: relative;
  overflow: hidden;
  background: #f5f5f5;
}

.bpmn-canvas {
  width: 100%;
  height: 100%;
  min-height: 400px;
}

.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.9);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  z-index: 1000;
}

.loading-overlay i {
  color: #1890ff;
}

.loading-overlay p {
  font-size: 14px;
  color: #666;
}

/* 属性面板样式 */
.properties-panel {
  width: 350px;
  background: white;
  border-left: 1px solid #e8e8e8;
  display: flex;
  flex-direction: column;
  transition: width 0.3s ease;
  box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
  position: relative;
}

.properties-panel.panel-collapsed {
  width: 0;
  overflow: hidden;
}

/* 左边缘折叠按钮样式 */
.panel-toggle-button {
  position: absolute;
  left: -16px;
  top: 50%;
  transform: translateY(-50%);
  width: 32px;
  height: 32px;
  background: #1890ff;
  border: 1px solid #1890ff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 1000;
  transition: all 0.3s ease;
  box-shadow: 0 2px 8px rgba(24, 144, 255, 0.3);
}

.panel-toggle-button:hover {
  background: #40a9ff;
  border-color: #40a9ff;
  transform: translateY(-50%) scale(1.1);
  box-shadow: 0 4px 12px rgba(24, 144, 255, 0.4);
}

.panel-toggle-button i {
  color: white;
  font-size: 14px;
  font-weight: bold;
}

/* 面板折叠时的按钮样式 */
.properties-panel.panel-collapsed .panel-toggle-button {
  left: -16px;
  background: #52c41a;
  border-color: #52c41a;
}

.properties-panel.panel-collapsed .panel-toggle-button:hover {
  background: #73d13d;
  border-color: #73d13d;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  background: #f8f9fa;
  border-bottom: 1px solid #e8e8e8;
  flex-shrink: 0;
}

.panel-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #333;
}

.panel-content {
  flex: 1;
  overflow: hidden;
  position: relative;
  padding: 0;
}

.properties-container {
  width: 100%;
  height: 100%;
  overflow-y: auto;
  padding: 0;
}

.no-selection {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #999;
  text-align: center;
  padding: 40px 20px;
  background: #fafafa;
}

.no-selection i {
  font-size: 3rem;
  margin-bottom: 16px;
  color: #ddd;
}

.no-selection p {
  margin: 0;
  font-size: 15px;
  line-height: 1.5;
  max-width: 200px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}

/* 自定义头部样式 */
.dialog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 0;
}

.dialog-header h3 {
  margin: 0;
  font-size: 1.2rem;
  font-weight: 600;
  color: #333;
}

.header-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}

.header-actions .p-button {
  color: #6c757d;
  transition: color 0.2s ease;
}

.header-actions .p-button:hover {
  color: #495057;
  background-color: rgba(0, 0, 0, 0.04);
}

/* 全屏模式样式 */
.bpmn-designer-dialog.fullscreen {
  position: fixed !important;
  top: 0 !important;
  left: 0 !important;
  width: 100vw !important;
  height: 100vh !important;
  max-width: none !important;
  max-height: none !important;
  margin: 0 !important;
  border-radius: 0 !important;
}

.bpmn-designer-dialog.fullscreen .p-dialog-content {
  height: calc(100vh - 60px) !important;
}

/* BPMN设计器全局样式 */
:deep(.bpmn-designer-dialog .p-dialog-content) {
  padding: 0;
  overflow: hidden;
}

/* 确保BPMN容器有正确的样式 */
.bpmn-canvas {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 400px;
}

/* BPMN.js 画布样式 */
.bpmn-canvas .djs-container {
  width: 100% !important;
  height: 100% !important;
}

/* 主设计区域布局 */
.designer-main {
  display: flex;
  flex: 1;
  overflow: hidden;
  position: relative;
}



/* 重复的属性面板样式已删除 */

.properties-panel.panel-collapsed {
  width: 48px;
}

/* 画布容器样式 */
.designer-container {
  flex: 1;
  position: relative;
  overflow: hidden;
  background: #f5f5f5;
}

/* 面板头部样式 */
.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: white;
  border-bottom: 1px solid #e8e8e8;
  min-height: 48px;
}

.panel-header h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: #333;
}

.panel-content {
  flex: 1;
  overflow-y: auto;
}

/* 调色板样式 - 集成到元素面板中 */
.djs-palette {
  position: static !important;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  padding: 0 !important;
  min-width: auto !important;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* 调色板分组样式 */
.djs-palette .group {
  margin-bottom: 16px;
}

.djs-palette .group-title {
  font-size: 12px;
  font-weight: 600;
  color: #666;
  margin-bottom: 8px;
  padding: 0 8px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

/* 调色板元素样式 */
.djs-palette .entry {
  display: flex !important;
  align-items: center;
  width: auto !important;
  height: 36px !important;
  margin: 0 4px 4px 4px !important;
  padding: 6px 8px !important;
  border: 1px solid transparent !important;
  border-radius: 4px !important;
  background: white !important;
  cursor: pointer !important;
  transition: all 0.2s ease !important;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1) !important;
  position: relative !important;
  overflow: visible !important;
}

.djs-palette .entry:hover {
  background: #f0f7ff !important;
  border-color: #1890ff !important;
  transform: none !important;
}

.djs-palette .entry.active {
  background: #e6f7ff !important;
  border-color: #1890ff !important;
}

.djs-palette .entry .djs-icon {
  width: 20px !important;
  height: 20px !important;
  margin: 0 8px 0 0 !important;
  filter: none !important;
  flex-shrink: 0;
}

.djs-palette .entry .entry-label {
  font-size: 13px;
  color: #333;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 缩放控制样式 */
.zoom-controls {
  display: flex;
  align-items: center;
  background: white;
  border: 1px solid #e8e8e8;
  border-radius: 4px;
  overflow: hidden;
}

.zoom-level {
  padding: 0 8px;
  font-size: 12px;
  color: #666;
  min-width: 40px;
  text-align: center;
  border-left: 1px solid #e8e8e8;
  border-right: 1px solid #e8e8e8;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.zoom-controls .p-button {
  min-width: 28px;
  height: 28px;
  border-radius: 0;
  padding: 0;
}

/* 画布提示样式已删除 */

/* 无选择状态提示 */
.no-selection {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  text-align: center;
  color: #6c757d;
  padding: 20px;
}

.no-selection i {
  font-size: 48px;
  margin-bottom: 16px;
  opacity: 0.3;
}

.no-selection p {
  margin: 0;
  font-size: 14px;
  line-height: 1.4;
}

/* 确保调色板条目正常显示 - 保持原生样式 */
.djs-palette .entry {
  display: block !important;
  width: 30px !important;
  height: 30px !important;
  margin: 2px !important;
  border: none !important;
  border-radius: 0 !important;
  background: transparent !important;
  cursor: pointer !important;
  transition: all 0.2s ease !important;
  box-shadow: none !important;
  position: relative !important;
  overflow: visible !important;
}

.djs-palette .entry:hover {
  background: rgba(59, 130, 246, 0.1) !important;
  transform: scale(1.1) !important;
}

.djs-palette .entry:active {
  transform: scale(0.95) !important;
}

.djs-palette .entry .djs-icon {
  width: 16px !important;
  height: 16px !important;
  margin: 7px !important;
  filter: none !important;
  transition: all 0.2s ease !important;
}

.djs-palette .entry:hover .djs-icon {
  filter: none !important;
  transform: none !important;
}

/* 中文汉化样式 - 直接CSS覆盖方案 */
.djs-palette .entry {
  position: relative;
  overflow: visible !important;
}

/* 直接覆盖title属性显示中文 */
.djs-palette .entry[title="Start Event"]:hover::after {
  content: "开始事件";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="End Event"]:hover::after {
  content: "结束事件";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="Task"]:hover::after {
  content: "任务";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="User Task"]:hover::after {
  content: "用户任务";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="Service Task"]:hover::after {
  content: "服务任务";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="Script Task"]:hover::after {
  content: "脚本任务";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="Manual Task"]:hover::after {
  content: "手工任务";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="Business Rule Task"]:hover::after {
  content: "业务规则任务";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="Exclusive Gateway"]:hover::after {
  content: "排他网关";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="Parallel Gateway"]:hover::after {
  content: "并行网关";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="Inclusive Gateway"]:hover::after {
  content: "包容网关";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="Sub Process"]:hover::after {
  content: "子流程";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="Data Object"]:hover::after {
  content: "数据对象";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

.djs-palette .entry[title="Text Annotation"]:hover::after {
  content: "文本注释";
  position: absolute;
  bottom: -30px;
  left: 50%;
  transform: translateX(-50%);
  background: rgba(0, 0, 0, 0.9);
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  font-size: 12px;
  white-space: nowrap;
  z-index: 1000;
  pointer-events: none;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}

/* 移除装饰效果，保持原生样式 */

/* 调色板分组样式 - 保持原生样式 */
.djs-palette .group {
  margin-bottom: 8px !important;
  padding: 4px 0 !important;
  border-bottom: none !important;
  position: relative !important;
}

.djs-palette .group:last-child {
  border-bottom: none !important;
  margin-bottom: 0 !important;
}

/* 调色板标题样式 - 保持原生样式 */
.djs-palette .group .label {
  font-size: 11px !important;
  color: #666 !important;
  margin-bottom: 4px !important;
  padding: 0 4px !important;
  font-weight: 500 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.5px !important;
  background: none !important;
  border-radius: 0 !important;
  text-align: left !important;
  border: none !important;
}

/* 调色板条目容器样式 - 保持原生样式 */
.djs-palette .entries {
  display: flex !important;
  flex-direction: column !important;
  gap: 2px !important;
  align-items: center !important;
  padding: 0 !important;
}

/* 调色板条目行样式 - 保持原生样式 */
.djs-palette .entry-row {
  display: flex !important;
  gap: 2px !important;
  justify-content: center !important;
  align-items: center !important;
  margin-bottom: 2px !important;
  padding: 0 !important;
}

/* 调色板元素中文标签 - 只在悬停时显示 */
.djs-palette .entry[title="Start Event"]:hover::after {
  content: "开始事件";
  position: absolute;
  bottom: -35px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 11px;
  color: #1f2937;
  white-space: nowrap;
  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15), 0 2px 6px rgba(0, 0, 0, 0.1);
  z-index: 1000;
  pointer-events: none;
  font-weight: 600;
  letter-spacing: 0.3px;
  backdrop-filter: blur(8px);
}

/* 其他元素的中文标签 - 悬停显示 */
.djs-palette .entry[title="End Event"]:hover::after,
.djs-palette .entry[title="Task"]:hover::after,
.djs-palette .entry[title="User Task"]:hover::after,
.djs-palette .entry[title="Service Task"]:hover::after,
.djs-palette .entry[title="Script Task"]:hover::after,
.djs-palette .entry[title="Manual Task"]:hover::after,
.djs-palette .entry[title="Business Rule Task"]:hover::after,
.djs-palette .entry[title="Send Task"]:hover::after,
.djs-palette .entry[title="Receive Task"]:hover::after,
.djs-palette .entry[title="Exclusive Gateway"]:hover::after,
.djs-palette .entry[title="Parallel Gateway"]:hover::after,
.djs-palette .entry[title="Inclusive Gateway"]:hover::after,
.djs-palette .entry[title="Event-based Gateway"]:hover::after,
.djs-palette .entry[title="Complex Gateway"]:hover::after,
.djs-palette .entry[title="Sub Process"]:hover::after,
.djs-palette .entry[title="Call Activity"]:hover::after,
.djs-palette .entry[title="Data Object"]:hover::after,
.djs-palette .entry[title="Data Store"]:hover::after,
.djs-palette .entry[title="Text Annotation"]:hover::after,
.djs-palette .entry[title="Group"]:hover::after,
.djs-palette .entry[title="Boundary Event"]:hover::after,
.djs-palette .entry[title="Intermediate Event"]:hover::after {
  position: absolute;
  bottom: -35px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 11px;
  color: #1f2937;
  white-space: nowrap;
  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid #e5e7eb;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15), 0 2px 6px rgba(0, 0, 0, 0.1);
  z-index: 1000;
  pointer-events: none;
  font-weight: 600;
  letter-spacing: 0.3px;
  backdrop-filter: blur(8px);
}

/* 具体的中文内容 */
.djs-palette .entry[title="End Event"]:hover::after { content: "结束事件"; }
.djs-palette .entry[title="Task"]:hover::after { content: "任务"; }
.djs-palette .entry[title="User Task"]:hover::after { content: "用户任务"; }
.djs-palette .entry[title="Service Task"]:hover::after { content: "服务任务"; }
.djs-palette .entry[title="Script Task"]:hover::after { content: "脚本任务"; }
.djs-palette .entry[title="Manual Task"]:hover::after { content: "手工任务"; }
.djs-palette .entry[title="Business Rule Task"]:hover::after { content: "业务规则任务"; }
.djs-palette .entry[title="Send Task"]:hover::after { content: "发送任务"; }
.djs-palette .entry[title="Receive Task"]:hover::after { content: "接收任务"; }
.djs-palette .entry[title="Exclusive Gateway"]:hover::after { content: "排他网关"; }
.djs-palette .entry[title="Parallel Gateway"]:hover::after { content: "并行网关"; }
.djs-palette .entry[title="Inclusive Gateway"]:hover::after { content: "包容网关"; }
.djs-palette .entry[title="Event-based Gateway"]:hover::after { content: "事件网关"; }
.djs-palette .entry[title="Complex Gateway"]:hover::after { content: "复杂网关"; }
.djs-palette .entry[title="Sub Process"]:hover::after { content: "子流程"; }
.djs-palette .entry[title="Call Activity"]:hover::after { content: "调用活动"; }
.djs-palette .entry[title="Data Object"]:hover::after { content: "数据对象"; }
.djs-palette .entry[title="Data Store"]:hover::after { content: "数据存储"; }
.djs-palette .entry[title="Text Annotation"]:hover::after { content: "文本注释"; }
.djs-palette .entry[title="Group"]:hover::after { content: "组"; }
.djs-palette .entry[title="Boundary Event"]:hover::after { content: "边界事件"; }
.djs-palette .entry[title="Intermediate Event"]:hover::after { content: "中间事件"; }

/* 属性面板样式优化 */
.bpp-properties-panel {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  padding: 20px !important;
  line-height: 1.6 !important;
}

.bpp-properties-panel .bpp-field {
  margin-bottom: 24px !important;
  padding: 12px 0 !important;
}

.bpp-properties-panel .bpp-field label {
  font-size: 14px !important;
  color: #333 !important;
  margin-bottom: 10px !important;
  display: block !important;
  font-weight: 500 !important;
  line-height: 1.4 !important;
}

.bpp-properties-panel .bpp-field input,
.bpp-properties-panel .bpp-field textarea,
.bpp-properties-panel .bpp-field select {
  width: 100% !important;
  padding: 12px 14px !important;
  border: 1px solid #ddd !important;
  border-radius: 8px !important;
  font-size: 14px !important;
  line-height: 1.5 !important;
  min-height: 44px !important;
  box-sizing: border-box !important;
  transition: all 0.2s ease !important;
}

.bpp-properties-panel .bpp-field input:focus,
.bpp-properties-panel .bpp-field textarea:focus,
.bpp-properties-panel .bpp-field select:focus {
  outline: none !important;
  border-color: #1890ff !important;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2) !important;
}

.bpp-properties-panel .bpp-field textarea {
  min-height: 100px !important;
  resize: vertical !important;
  padding: 12px 14px !important;
}

/* 属性面板分组样式 */
.bpp-properties-panel .bpp-group {
  margin-bottom: 28px !important;
  border: 1px solid #e8e8e8 !important;
  border-radius: 10px !important;
  overflow: hidden !important;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05) !important;
}

.bpp-properties-panel .bpp-group .bpp-group-header {
  background: #f8f9fa !important;
  padding: 16px 20px !important;
  font-weight: 600 !important;
  font-size: 15px !important;
  color: #333 !important;
  border-bottom: 1px solid #e8e8e8 !important;
  cursor: pointer !important;
  transition: background-color 0.2s !important;
  line-height: 1.4 !important;
}

.bpp-properties-panel .bpp-group .bpp-group-header:hover {
  background: #e9ecef !important;
}

.bpp-properties-panel .bpp-group .bpp-group-body {
  padding: 24px !important;
  background: white !important;
}

/* 属性面板标题样式 */
.bpp-properties-panel .bpp-properties-header {
  padding: 16px !important;
  background: #f8f9fa !important;
  border-bottom: 1px solid #e8e8e8 !important;
  font-size: 16px !important;
  font-weight: 600 !important;
  color: #333 !important;
}

/* 属性面板滚动条样式 */
.bpp-properties-panel::-webkit-scrollbar {
  width: 6px !important;
}

.bpp-properties-panel::-webkit-scrollbar-track {
  background: #f1f1f1 !important;
}

.bpp-properties-panel::-webkit-scrollbar-thumb {
  background: #c1c1c1 !important;
  border-radius: 3px !important;
}

.bpp-properties-panel::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8 !important;
}

/* 属性面板按钮样式 */
.bpp-properties-panel .bpp-button {
  padding: 10px 18px !important;
  margin: 6px 0 !important;
  border: 1px solid #ddd !important;
  border-radius: 6px !important;
  background: white !important;
  font-size: 13px !important;
  cursor: pointer !important;
  transition: all 0.2s !important;
  min-height: 40px !important;
  line-height: 1.4 !important;
}

.bpp-properties-panel .bpp-button:hover {
  background: #f5f5f5 !important;
  border-color: #1890ff !important;
}

/* 属性面板复选框和单选框样式 */
.bpp-properties-panel .bpp-checkbox,
.bpp-properties-panel .bpp-radio {
  margin: 12px 0 !important;
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  padding: 8px 0 !important;
}

.bpp-properties-panel .bpp-checkbox input,
.bpp-properties-panel .bpp-radio input {
  width: auto !important;
  min-height: auto !important;
  margin: 0 !important;
}

/* 属性面板下拉框样式 */
.bpp-properties-panel .bpp-dropdown {
  position: relative !important;
}

.bpp-properties-panel .bpp-dropdown select {
  appearance: none !important;
  background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6,9 12,15 18,9'%3e%3c/polyline%3e%3c/svg%3e") !important;
  background-repeat: no-repeat !important;
  background-position: right 12px center !important;
  background-size: 16px !important;
  padding-right: 40px !important;
}

/* 属性面板容器整体样式 */
.bpp-properties-panel .bpp-properties-container {
  padding: 0 !important;
  margin: 0 !important;
}

/* 属性面板条目间距 */
.bpp-properties-panel .bpp-properties-entry {
  margin-bottom: 20px !important;
  padding: 16px 0 !important;
  border-bottom: 1px solid #f0f0f0 !important;
}

/* 标签页样式 */
.properties-tabs {
  padding: 0;
  height: 100%;
}

.custom-tabs {
  height: 100%;
}

.custom-tabs :deep(.p-tabview-nav) {
  font-size: 12px;
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
}

.custom-tabs :deep(.p-tabview-nav .p-tabview-nav-link) {
  font-size: 12px;
  padding: 6px 8px;
  white-space: nowrap;
  flex-shrink: 0;
  min-width: auto;
}

.custom-tabs :deep(.p-tabview-panels) {
  padding: 12px;
  height: calc(100% - 36px);
  overflow-y: auto;
}

.tab-content {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.form-group label {
  font-size: 12px;
  font-weight: 500;
  color: #333;
  margin-bottom: 4px;
}

.form-group .w-full {
  width: 100%;
}

.form-group input,
.form-group textarea {
  padding: 6px 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 12px;
  transition: border-color 0.2s ease;
}

.form-group input:focus,
.form-group textarea:focus {
  outline: none;
  border-color: #007bff;
  box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
}

.form-group input[readonly] {
  background-color: #f8f9fa;
  color: #6c757d;
}

.tab-content {
  padding: 16px 0;
}

.form-group {
  margin-bottom: 16px;
}

.form-group label {
  display: block;
  margin-bottom: 6px;
  font-weight: 500;
  color: #333;
  font-size: 13px;
}

.form-group input,
.form-group textarea {
  width: 100%;
  padding: 6px 10px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  font-size: 13px;
  transition: all 0.3s;
}

.form-group input:focus,
.form-group textarea:focus {
  border-color: #4096ff;
  box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
  outline: none;
}

.form-group textarea {
  resize: vertical;
  min-height: 60px;
}

/* 监听器和扩展属性容器样式 */
.listeners-container,
.extensions-container {
  margin-top: 8px;
}

.listener-item,
.extension-item {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 8px;
  padding: 8px;
  background-color: #f9f9f9;
  border-radius: 4px;
}

.listener-item input,
.extension-item input {
  flex: 1;
  margin: 0;
}

/* 简化的Tabs组件样式，确保可见性和功能性 */
    .custom-tabs .p-tabs-nav {
      border-bottom: 1px solid #d9d9d9;
      padding: 0 10px;
      background: white !important;
    }

    .custom-tabs .p-tabs-nav .p-tabs-tab {
      padding: 10px 16px;
      font-size: 13px;
      background: white !important;
      color: #666;
    }

    .custom-tabs .p-tabs-nav .p-tabs-tab.p-highlight {
      color: #1890ff !important;
      border-bottom: 2px solid #1890ff !important;
      font-weight: 500;
    }

    .custom-tabs .p-tabs-panels {
      padding: 0;
      background: white !important;
    }

    /* 确保标签页内容区域可见 */
    .p-tabpanel {
      display: block !important;
    }

    .p-tabpanel:has(~ .p-tabpanel:not([aria-hidden="true"])) {
      display: none !important;
    }

    .p-tabpanel[aria-hidden="true"] {
      display: none !important;
    }

.bpp-properties-panel .bpp-properties-entry:last-child {
  border-bottom: none !important;
  margin-bottom: 0 !important;
}

/* 属性面板描述文本样式 */
.bpp-properties-panel .bpp-properties-description {
  font-size: 12px !important;
  color: #666 !important;
  margin-top: 6px !important;
  line-height: 1.4 !important;
  font-style: italic !important;
}

/* 属性面板错误提示样式 */
.bpp-properties-panel .bpp-error {
  color: #ff4d4f !important;
  font-size: 12px !important;
  margin-top: 4px !important;
  line-height: 1.4 !important;
}

/* 属性面板成功提示样式 */
.bpp-properties-panel .bpp-success {
  color: #52c41a !important;
  font-size: 12px !important;
  margin-top: 4px !important;
  line-height: 1.4 !important;
}

/* XML对话框样式 */
.xml-dialog :deep(.p-dialog-content) {
  padding: 0;
  height: calc(80vh - 60px);
  overflow: hidden;
}

.xml-content {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.xml-toolbar {
  display: flex;
  gap: 8px;
  padding: 12px 16px;
  background: #f8f9fa;
  border-bottom: 1px solid #e8e8e8;
  flex-shrink: 0;
}

.xml-editor {
  flex: 1;
  overflow: auto;
  background: #f5f5f5;
  padding: 16px;
}

.xml-editor pre {
  margin: 0;
  padding: 16px;
  background: white;
  border: 1px solid #e8e8e8;
  border-radius: 4px;
  font-family: 'Courier New', Consolas, monospace;
  font-size: 12px;
  line-height: 1.5;
  color: #333;
  white-space: pre-wrap;
  word-wrap: break-word;
  max-height: none;
  overflow: visible;
}

.xml-editor code {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
  background: transparent;
  padding: 0;
  border: none;
  border-radius: 0;
}
</style>

